﻿using System;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.Numerics;

namespace Umi.Web.Utils.Utils
{
    /// <summary>
    /// 字节数组工具类
    /// </summary>
    public static class ByteArrayUtils
    {
        /// <summary>
        /// 生成随机字节数组
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        public static byte[] GenerateRandomArray(int length)
        {
            using RandomNumberGenerator random = RandomNumberGenerator.Create();
            byte[] rtn = new byte[length];
            random.GetBytes(rtn);
            return rtn;
        }

        /// <summary>
        /// 比较两个数组
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static bool Compair(byte[] left, byte[] right)
        {
            if (left == null && right == null)
                return true;
            if (left == null || right == null)
                return false;
            int rtn = left.Length ^ right.Length;
            for (int i = 0; i < left.Length && i < right.Length; i++)
            {
                rtn |= (left[i] ^ right[i]);
            }
            return rtn == 0;
        }

        /// <summary>
        /// Hex字符串装换到字节数组
        /// </summary>
        /// <param name="hex">hex字符串</param>
        /// <returns></returns>
        public static byte[] HexToBitArray(string hex)
        {
            if (string.IsNullOrEmpty(hex))
                return null;
            hex = hex.Replace("-", "");
            if (hex.Length % 2 != 0)
                throw new InvalidOperationException($"Hex string length is {hex.Length}, not be allowed to convert to byte array");
            byte[] bitArray = new byte[hex.Length / 2];
            for (int i = 0; i < hex.Length; i += 2)
            {
                bitArray[i / 2] = byte.Parse(hex.Substring(i, 2), NumberStyles.AllowHexSpecifier);
            }
            return bitArray;
        }

        /// <summary>
        /// 字节数组转化为整数
        /// </summary>
        /// <param name="bit"></param>
        /// <returns></returns>
        public static long Byte2Int64(byte[] bit)
        {
            byte[] fill = new byte[8];
            if (bit.Length < 8)
                Array.Copy(bit, fill, bit.Length);
            else
                Array.Copy(bit, fill, 8);
            return BitConverter.ToInt64(fill, 0);
        }


        /// <summary>
        /// 字节数组转化为整数
        /// </summary>
        /// <param name="bit"></param>
        /// <returns></returns>
        public static int Byte2Int32(byte[] bit)
        {
            byte[] fill = new byte[4];
            if (bit.Length < 4)
                Array.Copy(bit, fill, bit.Length);
            else
                Array.Copy(bit, fill, 4);
            return BitConverter.ToInt32(fill, 0);
        }


        /// <summary>
        /// 字节数组转化为整数
        /// </summary>
        /// <param name="bit"></param>
        /// <returns></returns>
        public static short Byte2Int16(byte[] bit)
        {
            byte[] fill = new byte[2];
            if (bit.Length < 2)
                Array.Copy(bit, fill, bit.Length);
            else
                Array.Copy(bit, fill, 2);
            return BitConverter.ToInt16(fill, 0);
        }

        /// <summary>
        /// 字节数组转数字
        /// </summary>
        /// <param name="bit"></param>
        /// <returns></returns>
        public static BigInteger Byte2Integer(byte[] bit)
        {
            return new BigInteger(bit);
        }

        /// <summary>
        /// 数组位或运算
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static byte[] ArrayOr(byte[] left, byte[] right)
        {
            byte[] rtn = new byte[left.Length > right.Length ? left.Length : right.Length];
            for (int i = 0; i < left.Length || i < right.Length; i++)
            {
                byte l = i > left.Length ? (byte)0 : left[i];
                byte r = i > right.Length ? (byte)0 : right[i];
                rtn[i] = (byte)(l | r);
            }
            return rtn;
        }

        /// <summary>
        /// 数组位或运算
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static byte[] ArrayAnd(byte[] left, byte[] right)
        {
            byte[] rtn = new byte[left.Length > right.Length ? left.Length : right.Length];
            for (int i = 0; i < left.Length || i < right.Length; i++)
            {
                byte l = i > left.Length ? (byte)0 : left[i];
                byte r = i > right.Length ? (byte)0 : right[i];
                rtn[i] = (byte)(l & r);
            }
            return rtn;
        }

        /// <summary>
        /// 数组位或运算
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static byte[] ArrayXor(byte[] left, byte[] right)
        {
            byte[] rtn = new byte[left.Length > right.Length ? left.Length : right.Length];
            for (int i = 0; i < left.Length || i < right.Length; i++)
            {
                byte l = i > left.Length ? (byte)0 : left[i];
                byte r = i > right.Length ? (byte)0 : right[i];
                rtn[i] = (byte)(l ^ r);
            }
            return rtn;
        }

        /// <summary>
        /// 数组位或运算
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static byte[] ArrayNot(byte[] vals)
        {
            byte[] rtn = new byte[vals.Length];
            for (int i = 0; i < vals.Length; i++)
            {
                rtn[i] = (byte)~vals[i];
            }
            return rtn;
        }
    }
}
